<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>File Input Output</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'File Input Output' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../extensions.html">Kits</a></li><li><a href="index.html">Architecture32Kit</a></li><li><b>File Input Output</b></li></ul></div>
<p class="purpose">File Input Output  Access to external files.</p>

<ul class="toc"><li><a href="fio.html#SP1">&#167;1. Existence</a></li><li><a href="fio.html#SP2">&#167;2. Readiness</a></li><li><a href="fio.html#SP3">&#167;3. Open File</a></li><li><a href="fio.html#SP4">&#167;4. Close File</a></li><li><a href="fio.html#SP5">&#167;5. Get Character</a></li><li><a href="fio.html#SP6">&#167;6. Put Character</a></li><li><a href="fio.html#SP7">&#167;7. Print Line</a></li><li><a href="fio.html#SP8">&#167;8. Print Contents</a></li><li><a href="fio.html#SP9">&#167;9. Print Text</a></li><li><a href="fio.html#SP10">&#167;10. Serialising Tables</a></li><li><a href="fio.html#SP11">&#167;11. Internal file support</a></li><li><a href="fio.html#SP12">&#167;12. Errors</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Existence.</b>Determine whether a file exists on disc. Note that we have no concept of
directories, or the file system structure on the host machine: indeed, it
is entirely up to the Glulx VM what it does when asked to look for a file.
By convention, though, files for a project are stored in the same folder
as the story file when out in the wild; when a project is developed within
the Inform user interface, they are either (for preference) stored in a
<span class="extract"><span class="extract-syntax">Files</span></span> subfolder of the <span class="extract"><span class="extract-syntax">Materials</span></span> folder for a project, or else stored
alongside the Inform project file.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_Exists</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax">  </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">struc</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_MAGIC</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_MAGIC_VALUE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">) </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_BinaryMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_TextMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_fileref_create_by_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">fileusage_Data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">usage</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Glulx_ChangeAnyToCString</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax">), </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_fileref_does_file_exist</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Readiness.</b>One of our problems is that a file might be being used by another application:
perhaps even by another story file running in a second incarnation of Glulx,
like a parallel world of which we can know nothing. We actually want to
allow for this sort of thing, because one use for external files in I7
is as a sort of communications conduit for assisting applications.
</p>

<p class="commentary">Most operating systems solve this problem by means of locking a file, or
by creating a second lock-file, the existence of which indicates ownership
of the original. We haven't got much access to the file-system, though:
what we do is to set the first character of the file to an asterisk to
mark it as complete and ready for reading, or to a hyphen to mark it as
a work in progress.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">FileIO_Ready</span></span> determines whether or not a file is ready to be read
from: it has to exist on disc, and to be openable, and also to be ready
in having this marker asterisk.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">FileIO_MarkReady</span></span> changes the readiness state of a file, writing the
asterisk or hyphen into the initial character as needed.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_Ready</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax">  </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> </span><span class="identifier-syntax">str</span><span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">struc</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_MAGIC</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_MAGIC_VALUE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">) </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_BinaryMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_TextMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_fileref_create_by_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">fileusage_Data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">usage</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Glulx_ChangeAnyToCString</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax">), </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">glk_fileref_does_file_exist</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">) == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">str</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_stream_open_file</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">, </span><span class="identifier-syntax">filemode_Read</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_get_char_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">glk_stream_close</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="character-syntax">'*'</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_MarkReady</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">readiness</span><span class="plain-syntax">  </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> </span><span class="identifier-syntax">str</span><span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">struc</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_MAGIC</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_MAGIC_VALUE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">) </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_BinaryMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_TextMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_fileref_create_by_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">fileusage_Data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">usage</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Glulx_ChangeAnyToCString</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax">), </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">glk_fileref_does_file_exist</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">) == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"only existing files can be marked"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_STATUS_IS_CLOSED</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"only closed files can be marked"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">str</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_stream_open_file</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">, </span><span class="identifier-syntax">filemode_ReadWrite</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">glk_stream_set_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">); </span><span class="comment-syntax">seek start</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">readiness</span><span class="plain-syntax">) </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="character-syntax">'*'</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="character-syntax">'-'</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">glk_put_char_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">, </span><span class="identifier-syntax">ch</span><span class="plain-syntax">); </span><span class="comment-syntax">mark as complete</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">glk_stream_close</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Open File.</b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_Open</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">write_flag</span><span class="plain-syntax"> </span><span class="identifier-syntax">append_flag</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> </span><span class="identifier-syntax">str</span><span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> </span><span class="identifier-syntax">ix</span><span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> </span><span class="identifier-syntax">not_this_ifid</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax"> </span><span class="identifier-syntax">force_header</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">struc</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_MAGIC</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_MAGIC_VALUE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_STATUS_IS_CLOSED</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a file already open"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">) </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_BinaryMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_TextMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_fileref_create_by_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">fileusage_Data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">usage</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Glulx_ChangeAnyToCString</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax">), </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">write_flag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">append_flag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">filemode_WriteAppend</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">glk_fileref_does_file_exist</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">) == </span><span class="reserved-syntax">false</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">force_header</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">filemode_Write</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">filemode_Read</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">glk_fileref_does_file_exist</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">) == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a file which does not exist"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">str</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_stream_open_file</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">, </span><span class="identifier-syntax">mode</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">str</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a file but failed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax"> = </span><span class="identifier-syntax">str</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">write_flag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">append_flag</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_APPEND</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_WRITE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">glk_stream_set_current</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">append_flag</span><span class="plain-syntax"> == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">force_header</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"- "</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ix</span><span class="plain-syntax">=6: </span><span class="identifier-syntax">ix</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">UUID_ARRAY</span><span class="plain-syntax">-&gt;0: </span><span class="identifier-syntax">ix</span><span class="plain-syntax">++) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> (</span><span class="identifier-syntax">char</span><span class="plain-syntax">) </span><span class="identifier-syntax">UUID_ARRAY</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">ix</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">" "</span><span class="plain-syntax">, (</span><span class="reserved-syntax">string</span><span class="plain-syntax">) </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax">, </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_READ</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="character-syntax">'-'</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="character-syntax">'*'</span><span class="plain-syntax">) { </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> == </span><span class="character-syntax">'-'</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a file which was incomplete"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="character-syntax">' '</span><span class="plain-syntax">) { </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="character-syntax">'/'</span><span class="plain-syntax">) { </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="character-syntax">'/'</span><span class="plain-syntax">) { </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">owner</span><span class="plain-syntax"> = </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_IFID_OF_OWNER</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ix</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">owner</span><span class="plain-syntax"> == </span><span class="identifier-syntax">UUID_ARRAY</span><span class="plain-syntax">) </span><span class="identifier-syntax">ix</span><span class="plain-syntax"> = </span><span class="constant-syntax">8</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">owner</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (: </span><span class="identifier-syntax">ix</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">owner</span><span class="plain-syntax">-&gt;0: </span><span class="identifier-syntax">ix</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> == -1) { </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">owner</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">ix</span><span class="plain-syntax">) </span><span class="identifier-syntax">not_this_ifid</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> == </span><span class="character-syntax">' '</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">not_this_ifid</span><span class="plain-syntax"> == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="character-syntax">' '</span><span class="plain-syntax">) { </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= -1) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> == </span><span class="constant-syntax">10</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="constant-syntax">13</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">not_this_ifid</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_CLOSED</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">glk_stream_close</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"tried to open a file owned by another project"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    .</span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_CLOSED</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">glk_stream_close</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a file which seems to be malformed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Close File.</b>Note that a call to the following, in write mode, must be followed by a
<span class="extract"><span class="extract-syntax">glk_stream_set_current()</span></span>, or else the next print statement will run into
Glk errors.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_Close</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax">  </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> ~=</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_READ</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_WRITE</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_APPEND</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to close a file which is not open"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> ==</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_WRITE</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_APPEND</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">glk_stream_set_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">); </span><span class="comment-syntax">seek start</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">glk_put_char_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">, </span><span class="character-syntax">'*'</span><span class="plain-syntax">); </span><span class="comment-syntax">mark as complete</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">glk_stream_close</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_CLOSED</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. Get Character.</b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax">  </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_READ</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">glk_get_char_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. Put Character.</b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_PutC</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">char</span><span class="plain-syntax">  </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to write to a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> ~=</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_WRITE</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_APPEND</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"tried to write to a file which is not open for writing"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">glk_put_char_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">char</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Print Line.</b>We read characters from the supplied file until the next newline
character. (We allow for that to be encoded as either a single <span class="extract"><span class="extract-syntax">0a</span></span> or a
single <span class="extract"><span class="extract-syntax">0d</span></span>.) Each character is printed, and at the end we print a newline.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_PrintLine</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax">  </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to write to a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (::) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> == -1) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> == </span><span class="constant-syntax">10</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="constant-syntax">13</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^"</span><span class="plain-syntax">; </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">print</span><span class="plain-syntax"> (</span><span class="identifier-syntax">char</span><span class="plain-syntax">) </span><span class="identifier-syntax">ch</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Print Contents.</b>Repeating this until the file runs out is equivalent to the Unix command
<span class="extract"><span class="extract-syntax">cat</span></span>, that is, it copies the stream of characters from the file to the
output stream. (This might well be another file, just as with <span class="extract"><span class="extract-syntax">cat</span></span>, in
which case we have a copy utility.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_PrintContents</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">tab</span><span class="plain-syntax">  </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to access a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"printing text will not work with binary files"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FileIO_Open</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="reserved-syntax">false</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FileIO_PrintLine</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">)) ;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">FileIO_Close</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Print Text.</b>The following writes a given piece of text as the new content of the file,
either as the whole file (if <span class="extract"><span class="extract-syntax">append_flag</span></span> is false) or adding only to the
end (if true).
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_PutContents</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">text</span><span class="plain-syntax"> </span><span class="identifier-syntax">append_flag</span><span class="plain-syntax">  </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">str</span><span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> </span><span class="identifier-syntax">oldstream</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to access a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"writing text will not work with binary files"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">oldstream</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_stream_get_current</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">str</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_Open</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="reserved-syntax">true</span><span class="plain-syntax">, </span><span class="identifier-syntax">append_flag</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">str</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    @</span><span class="identifier-syntax">push</span><span class="plain-syntax"> </span><span class="identifier-syntax">say__p</span><span class="plain-syntax">; @</span><span class="identifier-syntax">push</span><span class="plain-syntax"> </span><span class="identifier-syntax">say__pc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ClearParagraphing</span><span class="plain-syntax">(19);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEXT_TY_Say</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">FileIO_Close</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">oldstream</span><span class="plain-syntax">) </span><span class="identifier-syntax">glk_stream_set_current</span><span class="plain-syntax">(</span><span class="identifier-syntax">oldstream</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    @</span><span class="identifier-syntax">pull</span><span class="plain-syntax"> </span><span class="identifier-syntax">say__pc</span><span class="plain-syntax">; @</span><span class="identifier-syntax">pull</span><span class="plain-syntax"> </span><span class="identifier-syntax">say__p</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Serialising Tables.</b>The most important data structures to "serialise" &mdash; that is, to convert
from their binary representations in memory into text representations in an
external file &mdash; are Tables. Here we only carry out the file-handling; the
actual translations are in "Tables.i6t".
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_PutTable</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">tab</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax">  </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">oldstream</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to write table to a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"writing a table will not work with binary files"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">oldstream</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_stream_get_current</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FileIO_Open</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="reserved-syntax">true</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TablePrint</span><span class="plain-syntax">(</span><span class="identifier-syntax">tab</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">FileIO_Close</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">oldstream</span><span class="plain-syntax">) </span><span class="identifier-syntax">glk_stream_set_current</span><span class="plain-syntax">(</span><span class="identifier-syntax">oldstream</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rv</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">IssueSavedUnstableTable</span><span class="plain-syntax">(</span><span class="identifier-syntax">tab</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_GetTable</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">tab</span><span class="plain-syntax">  </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to read table from a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"reading a table will not work with binary files"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FileIO_Open</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="reserved-syntax">false</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TableRead</span><span class="plain-syntax">(</span><span class="identifier-syntax">tab</span><span class="plain-syntax">, </span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">FileIO_Close</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. Internal file support.</b>Internal files (new in Inform with IE-0004) are handled very similarly to
external, though they are read-only, and there are no issues with ownership,
making everything much simpler.
</p>

<p class="commentary">Support so far is rudimentary, but this is a start.
</p>

<p class="commentary">File IDs are instance values for the enumerative kind "internal file", so
they range from 1 to NO_INTERNAL_FILES inclusive. Note that this is a different
kind from "external file", and Inform's typechecker does not allow either to
cast implicitly to the other. All the same the metadata structure for an
internal file is laid out very similarly to an external one, except that it
has an additional field AUXF_RESOURCE_ID holding the blorb resource ID for
the file; files are opened using resource IDs rather than filenames.
</p>

<p class="commentary">InternalFileReadChar(F, N) reads the data at position N in file F.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">InternalFileIO_Error</span><span class="plain-syntax"> </span><span class="identifier-syntax">file_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">err_text</span><span class="plain-syntax">  </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">file_id</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">file_id</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_INTERNAL_FILES</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^*** Error on unknown file: "</span><span class="plain-syntax">, (</span><span class="reserved-syntax">string</span><span class="plain-syntax">) </span><span class="identifier-syntax">err_text</span><span class="plain-syntax">, </span><span class="string-syntax">" ***^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfInternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">file_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^*** Error on file '"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            (</span><span class="reserved-syntax">string</span><span class="plain-syntax">) </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax">, </span><span class="string-syntax">"': "</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            (</span><span class="reserved-syntax">string</span><span class="plain-syntax">) </span><span class="identifier-syntax">err_text</span><span class="plain-syntax">, </span><span class="string-syntax">" ***^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_ERRONEOUS</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">IssueRTP</span><span class="plain-syntax">(</span><span class="string-syntax">"FileIOFailed"</span><span class="plain-syntax">, </span><span class="string-syntax">"Error handling external file."</span><span class="plain-syntax">, </span><span class="identifier-syntax">BasicInformKitRTPs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">InternalFileReadChar</span><span class="plain-syntax"> </span><span class="identifier-syntax">file_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">at</span><span class="plain-syntax"> </span><span class="identifier-syntax">resource_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">stream_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">now_at</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">file_id</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">file_id</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_INTERNAL_FILES</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">InternalFileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">file_id</span><span class="plain-syntax">, </span><span class="string-syntax">"file ID out of range"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfInternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">file_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> == </span><span class="identifier-syntax">AUXF_STATUS_IS_CLOSED</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">resource_id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_RESOURCE_ID</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">stream_id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_stream_open_resource_uni</span><span class="plain-syntax">(</span><span class="identifier-syntax">resource_id</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stream_id</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax"> = </span><span class="identifier-syntax">stream_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_READ</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">InternalFileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">file_id</span><span class="plain-syntax">, </span><span class="string-syntax">"unable to open for reading"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> == </span><span class="identifier-syntax">AUXF_STATUS_IS_ERRONEOUS</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">stream_id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">at</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">glk_stream_set_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">stream_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">seekmode_Start</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">glk_get_char_stream_uni</span><span class="plain-syntax">(</span><span class="identifier-syntax">stream_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">InternalFileIO_Line</span><span class="plain-syntax"> </span><span class="identifier-syntax">txt</span><span class="plain-syntax"> </span><span class="identifier-syntax">file_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">file_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> </span><span class="identifier-syntax">tsize</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEXT_TY_Transmute</span><span class="plain-syntax">(</span><span class="identifier-syntax">txt</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEXT_TY_Empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">txt</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">tsize</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PVFieldCapacity</span><span class="plain-syntax">(</span><span class="identifier-syntax">txt</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="reserved-syntax">true</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InternalFileReadChar</span><span class="plain-syntax">(</span><span class="identifier-syntax">file_id</span><span class="plain-syntax">, -1);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">10</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WritePVField</span><span class="plain-syntax">(</span><span class="identifier-syntax">txt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">); </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == -1) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pos</span><span class="plain-syntax">+1 &gt;= </span><span class="identifier-syntax">tsize</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SetPVFieldCapacity</span><span class="plain-syntax">(</span><span class="identifier-syntax">txt</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">*</span><span class="identifier-syntax">pos</span><span class="plain-syntax">) == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">tsize</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PVFieldCapacity</span><span class="plain-syntax">(</span><span class="identifier-syntax">txt</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WritePVField</span><span class="plain-syntax">(</span><span class="identifier-syntax">txt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">++, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WritePVField</span><span class="plain-syntax">(</span><span class="identifier-syntax">txt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pos</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">InternalFileReadWords</span><span class="plain-syntax"> </span><span class="identifier-syntax">file_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">at</span><span class="plain-syntax"> </span><span class="identifier-syntax">len</span><span class="plain-syntax"> </span><span class="identifier-syntax">buffer</span><span class="plain-syntax"> </span><span class="identifier-syntax">resource_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">stream_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">now_at</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">file_id</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">file_id</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_INTERNAL_FILES</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">InternalFileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">file_id</span><span class="plain-syntax">, </span><span class="string-syntax">"file ID out of range"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfInternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">file_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> == </span><span class="identifier-syntax">AUXF_STATUS_IS_CLOSED</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">resource_id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_RESOURCE_ID</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">stream_id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_stream_open_resource_uni</span><span class="plain-syntax">(</span><span class="identifier-syntax">resource_id</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stream_id</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax"> = </span><span class="identifier-syntax">stream_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_READ</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">InternalFileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">file_id</span><span class="plain-syntax">, </span><span class="string-syntax">"unable to open for reading"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> == </span><span class="identifier-syntax">AUXF_STATUS_IS_ERRONEOUS</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">stream_id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">at</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">glk_stream_set_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">stream_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">seekmode_Start</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">glk_get_buffer_stream_uni</span><span class="plain-syntax">(</span><span class="identifier-syntax">stream_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">len</span><span class="plain-syntax">) == </span><span class="identifier-syntax">len</span><span class="plain-syntax">) </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Errors.</b>This could be used for I/O errors of all kinds, but in fact we only need one:
see above.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">err_text</span><span class="plain-syntax">  </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^*** Error on unknown file: "</span><span class="plain-syntax">, (</span><span class="reserved-syntax">string</span><span class="plain-syntax">) </span><span class="identifier-syntax">err_text</span><span class="plain-syntax">, </span><span class="string-syntax">" ***^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^*** Error on file '"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            (</span><span class="reserved-syntax">string</span><span class="plain-syntax">) </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax">, </span><span class="string-syntax">"': "</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            (</span><span class="reserved-syntax">string</span><span class="plain-syntax">) </span><span class="identifier-syntax">err_text</span><span class="plain-syntax">, </span><span class="string-syntax">" ***^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">IssueRTP</span><span class="plain-syntax">(</span><span class="string-syntax">"FileIOFailed"</span><span class="plain-syntax">, </span><span class="string-syntax">"Error handling external file."</span><span class="plain-syntax">, </span><span class="identifier-syntax">BasicInformKitRTPs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="inot.html">&#10094;</a></li><li class="progresssection"><a href="cpblt.html">cpblt</a></li><li class="progresssection"><a href="infgl.html">infgl</a></li><li class="progresssection"><a href="glk.html">glk</a></li><li class="progresssection"><a href="strtp.html">strtp</a></li><li class="progresssection"><a href="stt.html">stt</a></li><li class="progresssection"><a href="mthmt.html">mthmt</a></li><li class="progresssection"><a href="chrst.html">chrst</a></li><li class="progresssection"><a href="inot.html">inot</a></li><li class="progresscurrent">fio</li><li class="progresssection"><a href="vnr.html">vnr</a></li><li class="progresssection"><a href="vrnm.html">vrnm</a></li><li class="progressnext"><a href="vnr.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

